<template>
  <div class="course-3d-list">
    <div ref="container3d" class="three-container"></div>
    
    <!-- UI控制层 -->
    <div class="ui-overlay">
      <!-- 顶部控制栏 -->
      <div class="top-controls">
        <div class="semester-selector">
          <button 
            v-for="(semester, index) in semesters" 
            :key="index"
            :class="['semester-btn', { active: currentSemester === index }]"
            @click="switchSemester(index)"
          >
            {{ semester.name }}
          </button>
        </div>
        
        <div class="search-controls">
          <div class="voice-search" @click="startVoiceSearch" :class="{ listening: isListening }">
            <span class="voice-icon">🎤</span>
            <span>{{ isListening ? '正在听...' : '语音搜索' }}</span>
          </div>
          <input 
            type="text" 
            v-model="searchQuery" 
            placeholder="搜索课程..."
            @input="filterCourses"
            class="search-input"
          >
        </div>
      </div>
      
      <!-- 课程信息悬浮卡片 -->
      <div 
        v-if="hoveredCourse" 
        class="course-info-card"
        :style="{ left: cardPosition.x + 'px', top: cardPosition.y + 'px' }"
      >
        <h3>{{ hoveredCourse.name }}</h3>
        <div class="course-details">
          <p><span class="label">学时:</span> {{ hoveredCourse.hours }}小时</p>
          <p><span class="label">学分:</span> {{ hoveredCourse.credits }}分</p>
          <p><span class="label">教师:</span> {{ hoveredCourse.teacher }}</p>
          <p><span class="label">进度:</span> {{ hoveredCourse.progress }}%</p>
        </div>
        <div class="status-indicator" :class="hoveredCourse.status">
          {{ getStatusText(hoveredCourse.status) }}
        </div>
        <div class="progress-bar">
          <div class="progress-fill" :style="{ width: hoveredCourse.progress + '%' }"></div>
        </div>
      </div>
      
      <!-- 加载指示器 -->
      <div v-if="isLoading" class="loading-indicator">
        <div class="spinner"></div>
        <p>正在加载3D课程场景...</p>
      </div>
      
      <!-- 帮助提示 -->
      <div class="help-tips">
        <div class="tip">💡 鼠标拖拽可旋转视角</div>
        <div class="tip">💡 滚轮缩放可调整距离</div>
        <div class="tip">💡 点击书本查看课程详情</div>
        <div class="tip">🎤 支持语音搜索课程</div>
      </div>
      
      <!-- 底部统计信息 -->
      <div class="bottom-stats">
        <div class="stat-item">
          <span class="stat-label">当前学期:</span>
          <span class="stat-value">{{ semesters[currentSemester].name }}</span>
        </div>
        <div class="stat-item">
          <span class="stat-label">课程总数:</span>
          <span class="stat-value">{{ filteredCourses.length }}</span>
        </div>
        <div class="stat-item">
          <span class="stat-label">已完成:</span>
          <span class="stat-value">{{ completedCount }}</span>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import * as THREE from 'three'
import { gsap } from 'gsap'
import { ThreeHelper, COLORS } from '@/utils/3d/ThreeHelper'

export default {
  name: 'Course3DList',
  data() {
    return {
      // 3D相关
      scene: null,
      camera: null,
      renderer: null,
      books: [],
      bookshelf: null,
      particleSystem: null,
      raycaster: new THREE.Raycaster(),
      mouse: new THREE.Vector2(),
      
      // 课程数据
      currentSemester: 0,
      semesters: [
        { name: '2025-1学期', courses: [] },
        { name: '2025-2学期', courses: [] },
        { name: '2024-2学期', courses: [] }
      ],
      allCourses: [
        {
          id: 1,
          name: '人工智能基础',
          hours: 48,
          credits: 3,
          teacher: '张教授',
          progress: 75,
          status: 'learning',
          semester: 0,
          description: '学习AI基础理论与实践'
        },
        {
          id: 2,
          name: '数据结构与算法',
          hours: 64,
          credits: 4,
          teacher: '李教授',
          progress: 100,
          status: 'completed',
          semester: 0,
          description: '计算机程序设计基础'
        },
        {
          id: 3,
          name: '计算机网络',
          hours: 48,
          credits: 3,
          teacher: '王教授',
          progress: 30,
          status: 'learning',
          semester: 0,
          description: '网络协议与通信原理'
        },
        {
          id: 4,
          name: '机器学习',
          hours: 56,
          credits: 3.5,
          teacher: '王教授',
          progress: 0,
          status: 'not-started',
          semester: 1,
          description: '机器学习算法与应用'
        },
        {
          id: 5,
          name: '深度学习',
          hours: 72,
          credits: 4.5,
          teacher: '刘教授',
          progress: 45,
          status: 'learning',
          semester: 1,
          description: '神经网络与深度学习'
        },
        {
          id: 6,
          name: 'Python编程',
          hours: 40,
          credits: 2.5,
          teacher: '陈教授',
          progress: 100,
          status: 'completed',
          semester: 1,
          description: 'Python语言程序设计'
        },
        {
          id: 7,
          name: '计算机视觉',
          hours: 60,
          credits: 4,
          teacher: '陈教授',
          progress: 100,
          status: 'completed',
          semester: 2,
          description: '图像处理与计算机视觉'
        },
        {
          id: 8,
          name: '自然语言处理',
          hours: 52,
          credits: 3.5,
          teacher: '赵教授',
          progress: 80,
          status: 'learning',
          semester: 2,
          description: 'NLP技术与应用'
        }
      ],
      
      // UI状态
      hoveredCourse: null,
      cardPosition: { x: 0, y: 0 },
      searchQuery: '',
      filteredCourses: [],
      isLoading: true,
      isListening: false,
      
      // 动画相关
      animationId: null,
      cameraRotation: 0
    }
  },
  
  computed: {
    completedCount() {
      if (!this.filteredCourses || !Array.isArray(this.filteredCourses)) {
        return 0
      }
      return this.filteredCourses.filter(course => course.status === 'completed').length
    }
  },
  
  mounted() {
    console.log('Course3DList 组件挂载开始')
    
    // 先设置课程数据
    this.initializeCoursesBySemester()
    
    // 等待DOM完全渲染后再初始化3D
    this.$nextTick(() => {
      console.log('DOM渲染完成，开始3D初始化')
      this.init3D()
      this.startAnimation()
      
      // 添加窗口调整监听
      window.addEventListener('resize', this.onWindowResize)
      
      // 短暂延迟后标记加载完成
      setTimeout(() => {
        console.log('标记加载完成')
        this.isLoading = false
        this.animateBookshelfEntry()
      }, 1000)
    })
  },
  
  beforeDestroy() {
    window.removeEventListener('resize', this.onWindowResize)
    if (this.animationId) {
      cancelAnimationFrame(this.animationId)
    }
    if (this.renderer) {
      this.renderer.dispose()
    }
  },
  
  methods: {
    initializeCoursesBySemester() {
      // 安全检查：确保数据结构正确
      if (!this.allCourses || !Array.isArray(this.allCourses)) {
        console.error('allCourses数据异常')
        return
      }
      
      console.log('所有课程数据:', this.allCourses)
      
      // 重置学期课程数据
      this.semesters.forEach(semester => {
        semester.courses = []
      })
      
      this.allCourses.forEach(course => {
        if (course.semester !== undefined && this.semesters[course.semester]) {
          this.semesters[course.semester].courses.push(course)
        }
      })
      
      this.filteredCourses = this.semesters[this.currentSemester]?.courses || []
      
      console.log('当前学期:', this.currentSemester)
      console.log('当前学期课程:', this.filteredCourses)
      console.log('所有学期分布:', this.semesters.map((sem, idx) => ({
        semester: idx,
        name: sem.name,
        count: sem.courses.length,
        courses: sem.courses.map(c => c.name)
      })))
    },
    
    init3D() {
      try {
        console.log('开始初始化3D场景...')
        
        // 检查WebGL支持
        if (!this.checkWebGLSupport()) {
          console.error('WebGL不支持')
          this.isLoading = false
          this.createFallbackScene()
          return
        }
        
        const container = this.$refs.container3d
        
        if (!container) {
          console.error('容器元素未找到')
          this.isLoading = false
          return
        }
        
        console.log('容器尺寸:', container.clientWidth, 'x', container.clientHeight)
        
        // 创建基础场景 - 手动实现确保稳定性
        this.scene = new THREE.Scene()
        this.scene.background = new THREE.Color(0x0a0a1a)
        
        // 创建相机
        this.camera = new THREE.PerspectiveCamera(
          75,
          container.clientWidth / container.clientHeight,
          0.1,
          1000
        )
        this.camera.position.set(0, 5, 25)
        this.camera.lookAt(0, 2, 0)
        
        // 创建渲染器
        this.renderer = new THREE.WebGLRenderer({ antialias: true })
        this.renderer.setSize(container.clientWidth, container.clientHeight)
        this.renderer.shadowMap.enabled = true
        this.renderer.shadowMap.type = THREE.PCFSoftShadowMap
        container.appendChild(this.renderer.domElement)
        
        console.log('基础场景创建成功')
        
        // 添加基础灯光
        const ambientLight = new THREE.AmbientLight(0x404040, 0.4)
        this.scene.add(ambientLight)
        
        const directionalLight = new THREE.DirectionalLight(0xffffff, 1.2)
        directionalLight.position.set(15, 15, 10)
        directionalLight.castShadow = true
        this.scene.add(directionalLight)
        
        console.log('基础灯光设置完成')
        
        // 先创建一个简单的测试立方体确保渲染正常
        const testGeometry = new THREE.BoxGeometry(2, 2, 2)
        const testMaterial = new THREE.MeshPhongMaterial({ color: 0x00ff88 })
        const testCube = new THREE.Mesh(testGeometry, testMaterial)
        testCube.position.y = 2
        this.scene.add(testCube)
        
        console.log('测试立方体创建完成')
        
        // 添加地面
        const floorGeometry = new THREE.PlaneGeometry(100, 100)
        const floorMaterial = new THREE.MeshPhongMaterial({ color: 0x1a1a2a })
        const floor = new THREE.Mesh(floorGeometry, floorMaterial)
        floor.rotation.x = -Math.PI / 2
        floor.position.y = -2
        floor.receiveShadow = true
        this.scene.add(floor)
        
        console.log('地面创建完成')
        
        // 立即渲染一帧
        this.renderer.render(this.scene, this.camera)
        console.log('初始渲染完成')
        
        // 异步加载复杂场景
        setTimeout(() => {
          this.loadComplexScene()
        }, 500)
        
        console.log('3D场景初始化完成!')
        
      } catch (error) {
        console.error('3D场景初始化失败:', error)
        this.isLoading = false
        
        // 显示fallback内容
        this.createFallbackScene()
      }
    },
    
    setupLights() {
      // 环境光
      const ambientLight = new THREE.AmbientLight(0x404040, 0.4)
      this.scene.add(ambientLight)
      
      // 主光源
      const directionalLight = new THREE.DirectionalLight(0xffffff, 1.2)
      directionalLight.position.set(15, 15, 10)
      directionalLight.castShadow = true
      directionalLight.shadow.mapSize.width = 2048
      directionalLight.shadow.mapSize.height = 2048
      this.scene.add(directionalLight)
      
      // 聚光灯 - 照亮书架
      const spotLight = new THREE.SpotLight(0x00ff88, 0.8, 50, Math.PI / 6, 0.1)
      spotLight.position.set(0, 20, 15)
      spotLight.target.position.set(0, 0, 0)
      spotLight.castShadow = true
      this.scene.add(spotLight)
      this.scene.add(spotLight.target)
      
      // 点光源 - 增加书本高亮
      const pointLight = new THREE.PointLight(0x1890ff, 0.6, 30)
      pointLight.position.set(-10, 8, 8)
      this.scene.add(pointLight)
      
      const pointLight2 = new THREE.PointLight(0xf39c12, 0.6, 30)
      pointLight2.position.set(10, 8, 8)
      this.scene.add(pointLight2)
    },
    
    createBookshelf() {
      const shelfGroup = new THREE.Group()
      
      // 书架材质
      const shelfMaterial = new THREE.MeshPhongMaterial({ 
        color: 0x8B4513,
        shininess: 30
      })
      
      // 创建多层书架
      for (let i = 0; i < 4; i++) {
        // 书架板
        const shelfGeometry = new THREE.BoxGeometry(24, 0.3, 4)
        const shelf = new THREE.Mesh(shelfGeometry, shelfMaterial)
        shelf.position.y = i * 4 - 4
        shelf.receiveShadow = true
        shelf.castShadow = true
        shelfGroup.add(shelf)
        
        // 书挡
        const bookendGeometry = new THREE.BoxGeometry(0.2, 3, 3)
        const leftBookend = new THREE.Mesh(bookendGeometry, shelfMaterial)
        leftBookend.position.set(-12, i * 4 - 2.5, 0)
        leftBookend.castShadow = true
        shelfGroup.add(leftBookend)
        
        const rightBookend = new THREE.Mesh(bookendGeometry, shelfMaterial)
        rightBookend.position.set(12, i * 4 - 2.5, 0)
        rightBookend.castShadow = true
        shelfGroup.add(rightBookend)
      }
      
      // 书架支撑柱
      const pillarGeometry = new THREE.BoxGeometry(0.6, 16, 0.6)
      const pillarMaterial = new THREE.MeshPhongMaterial({ color: 0x654321 })
      
      const pillarPositions = [-12, -4, 4, 12]
      for (let i = 0; i < pillarPositions.length; i++) {
        const x = pillarPositions[i]
        const pillar = new THREE.Mesh(pillarGeometry, pillarMaterial)
        pillar.position.set(x, 0, -1.8)
        pillar.castShadow = true
        shelfGroup.add(pillar)
      }
      
      // 顶部装饰
      const topGeometry = new THREE.BoxGeometry(26, 0.8, 5)
      const topMaterial = new THREE.MeshPhongMaterial({ color: 0x5d4037 })
      const top = new THREE.Mesh(topGeometry, topMaterial)
      top.position.y = 11
      top.castShadow = true
      shelfGroup.add(top)
      
      this.bookshelf = shelfGroup
      this.scene.add(shelfGroup)
    },
    
    createBooks() {
      console.log('创建书本开始...')
      console.log('当前filteredCourses:', this.filteredCourses)
      
      // 安全检查：确保books数组存在
      if (this.books && this.books.length > 0) {
        console.log('移除现有书本:', this.books.length)
        this.books.forEach(book => {
          this.scene.remove(book)
        })
      }
      this.books = []
      
      const currentCourses = this.filteredCourses || []
      console.log('要创建的课程数量:', currentCourses.length)
      
      if (currentCourses.length === 0) {
        console.warn('没有课程数据，无法创建书本')
        return
      }
      
      currentCourses.forEach((course, index) => {
        console.log(`创建第${index + 1}本书:`, course.name, '状态:', course.status)
        const book = this.createSingleBook(course, index)
        this.books.push(book)
        this.scene.add(book)
      })
      
      console.log('书本创建完成，总数:', this.books.length)
    },
    
    createSingleBook(course, index) {
      // 书本几何体 - 随机化尺寸
      const width = 1.2 + Math.random() * 0.6
      const height = 2.5 + Math.random() * 0.8
      const depth = 0.3 + Math.random() * 0.2
      
      const bookGeometry = new THREE.BoxGeometry(width, height, depth)
      
      // 根据课程状态选择材质和颜色
      let bookColor = 0x666666
      let emissive = 0x000000
      
      if (course.status === 'completed') {
        bookColor = 0xFFD700 // 金色
        emissive = 0x332200
      } else if (course.status === 'learning') {
        bookColor = 0x4CAF50 // 绿色
        emissive = 0x001100
      } else {
        bookColor = 0x666666 // 灰色
      }
      
      const bookMaterial = new THREE.MeshPhongMaterial({ 
        color: bookColor,
        emissive: emissive,
        shininess: 50
      })
      
      const book = new THREE.Mesh(bookGeometry, bookMaterial)
      
      // 位置计算 - 按书架层级排列
      const booksPerShelf = 6
      const shelfIndex = Math.floor(index / booksPerShelf)
      const positionInShelf = index % booksPerShelf
      
      const x = (positionInShelf - 2.5) * 3.5 + (Math.random() - 0.5) * 0.3
      const y = shelfIndex * 4 - 4 + height / 2 + 0.2
      const z = 1.5 + (Math.random() - 0.5) * 0.2
      
      console.log(`书本 "${course.name}" 位置:`, { x, y, z, shelfIndex, positionInShelf })
      
      book.position.set(x, y, z)
      
      // 轻微旋转
      book.rotation.y = (Math.random() - 0.5) * 0.2
      book.rotation.z = (Math.random() - 0.5) * 0.1
      
      // 添加课程数据
      book.userData = course
      
      // 添加书脊文字（简化版本）
      this.addBookSpineText(book, course.name)
      
      // 添加发光效果
      if (course.status === 'completed') {
        this.addGlowEffect(book)
      }
      
      book.castShadow = true
      book.receiveShadow = true
      
      return book
    },
    
    addBookSpineText(book, text) {
      // 创建简单的文字效果（使用线条）
      const textGeometry = new THREE.PlaneGeometry(0.1, 1.5)
      const textMaterial = new THREE.MeshBasicMaterial({ 
        color: 0xffffff,
        transparent: true,
        opacity: 0.8
      })
      const textMesh = new THREE.Mesh(textGeometry, textMaterial)
      textMesh.position.z = 0.16
      textMesh.position.y = 0.2
      book.add(textMesh)
    },
    
    addGlowEffect(book) {
      // 创建发光外框
      const glowGeometry = new THREE.BoxGeometry(
        book.geometry.parameters.width + 0.1,
        book.geometry.parameters.height + 0.1,
        book.geometry.parameters.depth + 0.1
      )
      const glowMaterial = new THREE.MeshBasicMaterial({
        color: 0xFFD700,
        transparent: true,
        opacity: 0.3,
        side: THREE.BackSide
      })
      const glow = new THREE.Mesh(glowGeometry, glowMaterial)
      book.add(glow)
      
      // 添加光环动画
      const animate = () => {
        glow.material.opacity = 0.2 + Math.sin(Date.now() * 0.003) * 0.1
      }
      glow.userData.animate = animate
    },
    
    createParticles() {
      try {
        // 手动创建粒子系统以避免依赖问题
        const particleCount = 1000
        const particles = new THREE.BufferGeometry()
        const positions = new Float32Array(particleCount * 3)
        
        for (let i = 0; i < particleCount * 3; i += 3) {
          positions[i] = (Math.random() - 0.5) * 50
          positions[i + 1] = (Math.random() - 0.5) * 50
          positions[i + 2] = (Math.random() - 0.5) * 50
        }
        
        particles.setAttribute('position', new THREE.BufferAttribute(positions, 3))
        
        const material = new THREE.PointsMaterial({ 
          color: 0x00ff88,
          size: 0.05,
          transparent: true,
          opacity: 0.6
        })
        
        this.particleSystem = new THREE.Points(particles, material)
        this.scene.add(this.particleSystem)
        
      } catch (error) {
        console.warn('粒子系统创建失败，跳过:', error)
      }
    },
    
    createEnvironment() {
      // 创建地面
      const floorGeometry = new THREE.PlaneGeometry(100, 100)
      const floorMaterial = new THREE.MeshPhongMaterial({ 
        color: 0x1a1a2a,
        shininess: 100
      })
      const floor = new THREE.Mesh(floorGeometry, floorMaterial)
      floor.rotation.x = -Math.PI / 2
      floor.position.y = -8
      floor.receiveShadow = true
      this.scene.add(floor)
      
      // 创建背景墙
      const wallGeometry = new THREE.PlaneGeometry(100, 50)
      const wallMaterial = new THREE.MeshPhongMaterial({ 
        color: 0x0a0a1a,
        transparent: true,
        opacity: 0.7
      })
      const wall = new THREE.Mesh(wallGeometry, wallMaterial)
      wall.position.z = -10
      wall.position.y = 10
      this.scene.add(wall)
    },
    
    setupMouseEvents() {
      const container = this.$refs.container3d
      let isDragging = false
      let previousMousePosition = { x: 0, y: 0 }
      
      // 鼠标移动事件
      container.addEventListener('mousemove', this.onMouseMove)
      container.addEventListener('click', this.onMouseClick)
      container.addEventListener('wheel', this.onMouseWheel)
      
      // 鼠标拖拽旋转
      container.addEventListener('mousedown', (event) => {
        isDragging = true
        previousMousePosition = { x: event.clientX, y: event.clientY }
        container.style.cursor = 'grabbing'
      })
      
      container.addEventListener('mouseup', () => {
        isDragging = false
        container.style.cursor = 'grab'
      })
      
      container.addEventListener('mousemove', (event) => {
        if (isDragging) {
          const deltaMove = {
            x: event.clientX - previousMousePosition.x,
            y: event.clientY - previousMousePosition.y
          }
          
          // 更新相机旋转
          this.cameraRotation += deltaMove.x * 0.005
          
          // 限制上下旋转
          const phi = Math.max(0.1, Math.min(Math.PI - 0.1, Math.PI / 2 - deltaMove.y * 0.005))
          
          // 更新相机位置
          const radius = 25
          this.camera.position.x = radius * Math.sin(phi) * Math.cos(this.cameraRotation)
          this.camera.position.z = radius * Math.sin(phi) * Math.sin(this.cameraRotation)
          this.camera.position.y = radius * Math.cos(phi)
          this.camera.lookAt(0, 0, 0)
          
          previousMousePosition = { x: event.clientX, y: event.clientY }
        }
      })
      
      container.style.cursor = 'grab'
    },
    
    onMouseMove(event) {
      if (!this.$refs.container3d || !this.books || this.books.length === 0) return
      
      const rect = this.$refs.container3d.getBoundingClientRect()
      this.mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1
      this.mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1
      
      // 射线检测
      this.raycaster.setFromCamera(this.mouse, this.camera)
      const intersects = this.raycaster.intersectObjects(this.books)
      
      if (intersects.length > 0) {
        const intersectedBook = intersects[0].object
        this.hoveredCourse = intersectedBook.userData
        this.cardPosition = {
          x: Math.min(event.clientX + 10, window.innerWidth - 300),
          y: Math.max(event.clientY - 10, 10)
        }
        
        // 书本悬浮效果
        gsap.to(intersectedBook.position, {
          duration: 0.3,
          z: intersectedBook.position.z + 0.5,
          ease: "power2.out"
        })
        gsap.to(intersectedBook.rotation, {
          duration: 0.3,
          y: intersectedBook.rotation.y + 0.1,
          ease: "power2.out"
        })
        
        // 重置其他书本 - 安全检查
        if (this.books && this.books.length > 0) {
          this.books.forEach(book => {
            if (book !== intersectedBook) {
              gsap.to(book.position, {
                duration: 0.3,
                z: book.userData.originalZ || book.position.z,
                ease: "power2.out"
              })
              gsap.to(book.rotation, {
                duration: 0.3,
                y: book.userData.originalRotationY || 0,
                ease: "power2.out"
              })
            }
          })
        }
      } else {
        this.hoveredCourse = null
        
        // 重置所有书本位置 - 安全检查
        if (this.books && this.books.length > 0) {
          this.books.forEach(book => {
            if (!book.userData.originalZ) {
              book.userData.originalZ = book.position.z
              book.userData.originalRotationY = book.rotation.y
            }
            gsap.to(book.position, {
              duration: 0.3,
              z: book.userData.originalZ,
              ease: "power2.out"
            })
            gsap.to(book.rotation, {
              duration: 0.3,
              y: book.userData.originalRotationY,
              ease: "power2.out"
            })
          })
        }
      }
    },
    
    onMouseClick(event) {
      if (!this.books || this.books.length === 0) return
      
      this.raycaster.setFromCamera(this.mouse, this.camera)
      const intersects = this.raycaster.intersectObjects(this.books)
      
      if (intersects.length > 0) {
        const course = intersects[0].object.userData
        this.enterCourse(course)
      }
    },
    
    onMouseWheel(event) {
      event.preventDefault()
      const delta = event.deltaY * 0.001
      
      // 计算当前相机到原点的距离
      const currentDistance = this.camera.position.length()
      const newDistance = Math.max(10, Math.min(50, currentDistance + delta * 10))
      
      // 保持相机方向，只调整距离
      this.camera.position.normalize().multiplyScalar(newDistance)
    },
    
    switchSemester(index) {
      if (index === this.currentSemester) return
      
      this.currentSemester = index
      this.filteredCourses = this.semesters[index]?.courses || []
      
      // 书本切换动画
      this.animateSemesterTransition()
    },
    
    animateSemesterTransition() {
      // 先让当前书本消失 - 安全检查
      if (this.books && this.books.length > 0) {
        this.books.forEach((book, index) => {
          gsap.to(book.position, {
            duration: 0.5,
            y: book.position.y - 10,
            delay: index * 0.05,
            ease: "power2.in"
          })
          gsap.to(book.rotation, {
            duration: 0.5,
            z: book.rotation.z + Math.PI,
            delay: index * 0.05,
            ease: "power2.in"
          })
        })
      }
      
      // 延迟后创建新书本
      setTimeout(() => {
        this.createBooks()
        this.animateBookshelfEntry()
      }, 800)
    },
    
    animateBookshelfEntry() {
      // 书本入场动画 - 安全检查
      if (!this.books || this.books.length === 0) return
      
      this.books.forEach((book, index) => {
        const originalY = book.position.y
        book.position.y = originalY + 15
        book.rotation.x = Math.PI
        
        gsap.to(book.position, {
          duration: 1,
          y: originalY,
          delay: index * 0.1,
          ease: "bounce.out"
        })
        gsap.to(book.rotation, {
          duration: 1,
          x: book.userData.originalRotationX || 0,
          delay: index * 0.1,
          ease: "power2.out"
        })
      })
    },
    
    startVoiceSearch() {
      if ('webkitSpeechRecognition' in window || 'SpeechRecognition' in window) {
        const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition
        const recognition = new SpeechRecognition()
        
        recognition.lang = 'zh-CN'
        recognition.continuous = false
        recognition.interimResults = false
        
        this.isListening = true
        
        recognition.onresult = (event) => {
          const result = event.results[0][0].transcript
          this.searchQuery = result
          this.filterCourses()
          this.isListening = false
        }
        
        recognition.onerror = (event) => {
          console.error('语音识别错误:', event.error)
          this.isListening = false
          alert('语音识别失败，请重试')
        }
        
        recognition.onend = () => {
          this.isListening = false
        }
        
        recognition.start()
      } else {
        alert('浏览器不支持语音识别功能')
      }
    },
    
    filterCourses() {
      const semesterCourses = this.semesters[this.currentSemester]?.courses || []
      
      if (!this.searchQuery.trim()) {
        this.filteredCourses = semesterCourses
      } else {
        const query = this.searchQuery.toLowerCase()
        this.filteredCourses = semesterCourses.filter(course =>
          course.name.toLowerCase().includes(query) ||
          course.teacher.toLowerCase().includes(query) ||
          course.description.toLowerCase().includes(query)
        )
      }
      
      // 重新创建书本
      this.createBooks()
      this.animateBookshelfEntry()
    },
    
    enterCourse(course) {
      if (!this.books || this.books.length === 0 || !course) return
      
      // 书本展开动画
      const selectedBook = this.books.find(book => book.userData && book.userData.id === course.id)
      if (selectedBook) {
        // 创建展开效果
        gsap.to(selectedBook.scale, {
          duration: 0.8,
          x: 5,
          y: 5,
          z: 0.1,
          ease: "power2.out"
        })
        
        gsap.to(selectedBook.position, {
          duration: 0.8,
          z: 8,
          ease: "power2.out"
        })
        
        gsap.to(selectedBook.rotation, {
          duration: 0.8,
          y: Math.PI / 4,
          ease: "power2.out"
        })
        
        // 显示加载效果
        setTimeout(() => {
          // 这里可以跳转到3D课堂页面
          this.$router.push({
            path: '/3d-classroom',
            query: { courseId: course.id }
          })
        }, 1200)
      }
    },
    
    getStatusText(status) {
      const statusMap = {
        'completed': '已完成',
        'learning': '学习中',
        'not-started': '未开始'
      }
      return statusMap[status] || '未知'
    },
    
    startAnimation() {
      const animate = () => {
        this.animationId = requestAnimationFrame(animate)
        
        // 粒子旋转
        if (this.particleSystem) {
          this.particleSystem.rotation.y += 0.0005
          this.particleSystem.rotation.x += 0.0002
        }
        
        // 书本发光动画 - 安全检查
        if (this.books && this.books.length > 0) {
          this.books.forEach(book => {
            if (book.children && book.children.length > 0) {
              book.children.forEach(child => {
                if (child.userData && child.userData.animate) {
                  child.userData.animate()
                }
              })
            }
          })
        }
        
        // 自动旋转相机（缓慢）
        if (!this.hoveredCourse) {
          this.cameraRotation += 0.0002
          const radius = this.camera.position.length()
          const currentY = this.camera.position.y
          this.camera.position.x = radius * Math.cos(this.cameraRotation) * Math.sin(Math.acos(currentY / radius))
          this.camera.position.z = radius * Math.sin(this.cameraRotation) * Math.sin(Math.acos(currentY / radius))
          this.camera.lookAt(0, 0, 0)
        }
        
        this.renderer.render(this.scene, this.camera)
      }
      animate()
    },
    
    onWindowResize() {
      const container = this.$refs.container3d
      if (this.camera && this.renderer && container) {
        this.camera.aspect = container.clientWidth / container.clientHeight
        this.camera.updateProjectionMatrix()
        this.renderer.setSize(container.clientWidth, container.clientHeight)
      }
    },
    
    checkWebGLSupport() {
      try {
        const canvas = document.createElement('canvas')
        const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl')
        return !!gl
      } catch (e) {
        return false
      }
    },
    
    loadComplexScene() {
      try {
        console.log('开始加载复杂场景...')
        
        // 清除测试立方体
        const testCube = this.scene.children.find(child => child.geometry instanceof THREE.BoxGeometry)
        if (testCube) {
          this.scene.remove(testCube)
        }
        
        // 添加更多灯光
        this.setupLights()
        console.log('完整灯光设置完成')
        
        // 创建书架
        this.createBookshelf()
        console.log('书架创建完成')
        
        // 创建书本
        this.createBooks()
        console.log('书本创建完成')
        
        // 创建粒子效果
        this.createParticles()
        console.log('粒子系统创建完成')
        
        // 创建环境装饰
        this.createEnvironment()
        console.log('环境装饰创建完成')
        
        // 添加鼠标事件
        this.setupMouseEvents()
        console.log('鼠标事件绑定完成')
        
        console.log('复杂场景加载完成!')
        
        // 强制渲染一帧以确保所有对象都显示
        this.renderer.render(this.scene, this.camera)
        
      } catch (error) {
        console.error('复杂场景加载失败:', error)
        // 保持基础场景运行
      }
    },
    
    createFallbackScene() {
      console.log('创建fallback场景')
      const container = this.$refs.container3d
      
      // 创建简单的fallback显示
      const fallbackDiv = document.createElement('div')
      fallbackDiv.style.cssText = `
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        color: white;
        text-align: center;
        font-size: 18px;
        z-index: 1000;
      `
      fallbackDiv.innerHTML = `
        <div>🚧 3D场景加载失败</div>
        <div style="font-size: 14px; margin-top: 10px; opacity: 0.7;">
          请尝试刷新页面或使用支持WebGL的浏览器
        </div>
        <button onclick="location.reload()" style="
          margin-top: 15px;
          padding: 8px 16px;
          background: #00ff88;
          color: black;
          border: none;
          border-radius: 5px;
          cursor: pointer;
        ">重新加载</button>
      `
      container.appendChild(fallbackDiv)
    }
  }
}
</script>

<style scoped lang="scss">
.course-3d-list {
  position: relative;
  width: 100%;
  height: 100vh;
  overflow: hidden;
  background: linear-gradient(135deg, #0a0a1a 0%, #1a1a2e 50%, #16213e 100%);
}

.three-container {
  width: 100%;
  height: 100%;
  position: relative;
}

.ui-overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 100;
  
  > * {
    pointer-events: auto;
  }
}

.top-controls {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px;
  background: rgba(0, 0, 0, 0.4);
  backdrop-filter: blur(15px);
  border-radius: 0 0 25px 25px;
  border: 1px solid rgba(0, 255, 136, 0.2);
}

.semester-selector {
  display: flex;
  gap: 12px;
  
  .semester-btn {
    padding: 12px 24px;
    background: rgba(255, 255, 255, 0.1);
    color: white;
    border: 2px solid transparent;
    border-radius: 25px;
    cursor: pointer;
    transition: all 0.4s;
    font-weight: 500;
    position: relative;
    overflow: hidden;
    
    &::before {
      content: '';
      position: absolute;
      top: 0;
      left: -100%;
      width: 100%;
      height: 100%;
      background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
      transition: left 0.5s;
    }
    
    &:hover {
      background: rgba(255, 255, 255, 0.15);
      border-color: #00ff88;
      transform: translateY(-2px);
      box-shadow: 0 5px 15px rgba(0, 255, 136, 0.3);
      
      &::before {
        left: 100%;
      }
    }
    
    &.active {
      background: linear-gradient(135deg, #00ff88 0%, #00d4aa 100%);
      border-color: #00ff88;
      box-shadow: 0 0 25px rgba(0, 255, 136, 0.6);
      transform: scale(1.05);
    }
  }
}

.search-controls {
  display: flex;
  gap: 15px;
  align-items: center;
  
  .voice-search {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 12px 20px;
    background: rgba(255, 255, 255, 0.1);
    color: white;
    border-radius: 25px;
    cursor: pointer;
    transition: all 0.3s;
    border: 2px solid transparent;
    
    &:hover {
      background: rgba(255, 255, 255, 0.2);
      transform: translateY(-2px);
      border-color: #1890ff;
    }
    
    &.listening {
      background: linear-gradient(135deg, #ff4d4f 0%, #ff7875 100%);
      animation: pulse 1.5s infinite;
      border-color: #ff4d4f;
    }
    
    .voice-icon {
      font-size: 16px;
    }
  }
  
  .search-input {
    padding: 12px 20px;
    background: rgba(255, 255, 255, 0.1);
    color: white;
    border: 2px solid transparent;
    border-radius: 25px;
    width: 320px;
    font-size: 14px;
    transition: all 0.3s;
    
    &::placeholder {
      color: rgba(255, 255, 255, 0.7);
    }
    
    &:focus {
      outline: none;
      border-color: #00ff88;
      background: rgba(255, 255, 255, 0.15);
      box-shadow: 0 0 20px rgba(0, 255, 136, 0.3);
      transform: scale(1.02);
    }
  }
}

.course-info-card {
  position: absolute;
  background: rgba(0, 0, 0, 0.95);
  color: white;
  padding: 25px;
  border-radius: 20px;
  backdrop-filter: blur(20px);
  border: 2px solid rgba(0, 255, 136, 0.3);
  box-shadow: 0 15px 35px rgba(0, 0, 0, 0.6);
  min-width: 280px;
  max-width: 350px;
  z-index: 1000;
  transform-origin: top left;
  animation: cardFadeIn 0.3s ease-out;
  
  h3 {
    margin: 0 0 15px 0;
    color: #00ff88;
    font-size: 18px;
    font-weight: 600;
  }
  
  .course-details {
    margin-bottom: 15px;
    
    p {
      margin: 8px 0;
      font-size: 14px;
      display: flex;
      justify-content: space-between;
      
      .label {
        color: #00ff88;
        font-weight: 500;
      }
    }
  }
  
  .status-indicator {
    padding: 6px 15px;
    border-radius: 15px;
    font-size: 12px;
    text-align: center;
    font-weight: 500;
    margin-bottom: 15px;
    
    &.completed {
      background: linear-gradient(135deg, #FFD700 0%, #FFA500 100%);
      color: #333;
      box-shadow: 0 0 15px rgba(255, 215, 0, 0.5);
    }
    
    &.learning {
      background: linear-gradient(135deg, #4CAF50 0%, #45a049 100%);
      color: white;
      box-shadow: 0 0 15px rgba(76, 175, 80, 0.5);
    }
    
    &.not-started {
      background: linear-gradient(135deg, #666 0%, #555 100%);
      color: white;
    }
  }
  
  .progress-bar {
    width: 100%;
    height: 6px;
    background: rgba(255, 255, 255, 0.2);
    border-radius: 3px;
    overflow: hidden;
    
    .progress-fill {
      height: 100%;
      background: linear-gradient(90deg, #00ff88, #00d4aa);
      border-radius: 3px;
      transition: width 0.3s ease;
    }
  }
}

.loading-indicator {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
  color: white;
  
  .spinner {
    width: 60px;
    height: 60px;
    border: 4px solid rgba(255, 255, 255, 0.3);
    border-top: 4px solid #00ff88;
    border-radius: 50%;
    animation: spin 1s linear infinite;
    margin: 0 auto 25px;
  }
  
  p {
    font-size: 16px;
    margin: 0;
    color: #00ff88;
  }
}

.help-tips {
  position: absolute;
  bottom: 80px;
  left: 20px;
  
  .tip {
    background: rgba(0, 0, 0, 0.8);
    color: white;
    padding: 10px 18px;
    border-radius: 25px;
    margin-bottom: 12px;
    font-size: 14px;
    backdrop-filter: blur(15px);
    border: 1px solid rgba(0, 255, 136, 0.2);
    transition: all 0.3s;
    
    &:hover {
      background: rgba(0, 255, 136, 0.1);
      border-color: #00ff88;
      transform: translateX(5px);
    }
  }
}

.bottom-stats {
  position: absolute;
  bottom: 20px;
  right: 20px;
  display: flex;
  gap: 20px;
  
  .stat-item {
    background: rgba(0, 0, 0, 0.8);
    color: white;
    padding: 12px 20px;
    border-radius: 20px;
    backdrop-filter: blur(15px);
    border: 1px solid rgba(0, 255, 136, 0.2);
    font-size: 14px;
    
    .stat-label {
      color: #00ff88;
      margin-right: 8px;
    }
    
    .stat-value {
      font-weight: 600;
    }
  }
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

@keyframes pulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.05); }
}

@keyframes cardFadeIn {
  from {
    opacity: 0;
    transform: scale(0.8) translateY(-10px);
  }
  to {
    opacity: 1;
    transform: scale(1) translateY(0);
  }
}

// 响应式设计
@media (max-width: 768px) {
  .top-controls {
    flex-direction: column;
    gap: 15px;
    padding: 15px;
  }
  
  .semester-selector {
    justify-content: center;
    flex-wrap: wrap;
  }
  
  .search-controls {
    width: 100%;
    justify-content: center;
    
    .search-input {
      width: 250px;
    }
  }
  
  .course-info-card {
    max-width: 250px;
    padding: 20px;
  }
  
  .bottom-stats {
    flex-direction: column;
    bottom: 10px;
    right: 10px;
    gap: 8px;
    
    .stat-item {
      padding: 8px 15px;
      font-size: 12px;
    }
  }
  
  .help-tips {
    display: none;
  }
}
</style> 